home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / share / python-support / python-rdflib / rdflib / Collection.py < prev    next >
Encoding:
Python Source  |  2007-04-04  |  5.2 KB  |  185 lines

  1. from rdflib import RDF, BNode, Literal
  2. from rdflib.Graph import Graph
  3.  
  4. class Collection(object):
  5.     """
  6.     See 3.3.5 Emulating container types: http://docs.python.org/ref/sequence-types.html#l2h-232
  7.     
  8.     >>> listName = BNode()
  9.     >>> g = Graph('IOMemory')
  10.     >>> listItem1 = BNode()
  11.     >>> listItem2 = BNode()
  12.     >>> g.add((listName,RDF.first,Literal(1)))
  13.     >>> g.add((listName,RDF.rest,listItem1))
  14.     >>> g.add((listItem1,RDF.first,Literal(2)))
  15.     >>> g.add((listItem1,RDF.rest,listItem2))
  16.     >>> g.add((listItem2,RDF.rest,RDF.nil))
  17.     >>> g.add((listItem2,RDF.first,Literal(3)))
  18.     >>> c=Collection(g,listName)
  19.     >>> print list(c)
  20.     [rdflib.Literal('1', language=None, datatype=rdflib.URIRef('http://www.w3.org/2001/XMLSchema#int')), rdflib.Literal('2', language=None, datatype=rdflib.URIRef('http://www.w3.org/2001/XMLSchema#int')), rdflib.Literal('3', language=None, datatype=rdflib.URIRef('http://www.w3.org/2001/XMLSchema#int'))]
  21.     >>> 1 in c
  22.     True
  23.     >>> len(c)
  24.     3
  25.     >>> c._get_container(1) == listItem1
  26.     True
  27.     >>> c.index(Literal(2)) == 1
  28.     True
  29.     """
  30.     def __init__(self, graph, uri, seq=[]):
  31.         self.graph = graph
  32.         self.uri = uri or BNode()
  33.         for item in seq:
  34.             self.append(item)
  35.  
  36.     def _get_container(self, index):
  37.         """Gets the first, rest holding node at index."""
  38.         assert isinstance(index, int)
  39.         graph = self.graph
  40.         container = self.uri
  41.         i = 0
  42.         while i<index:
  43.             i += 1
  44.             container = graph.value(container, RDF.rest)
  45.             if container is None:
  46.                 break
  47.         return container
  48.  
  49.     def __len__(self):
  50.         """length of items in collection."""
  51.         count = 0
  52.         for item in self.graph.items(self.uri):
  53.             count += 1
  54.         return count
  55.  
  56.     def index(self, item):
  57.         """
  58.         Returns the 0-based numerical index of the item in the list          
  59.         """
  60.         listName = self.uri
  61.         index = 0
  62.         while True:
  63.             if (listName,RDF.first,item) in self.graph:
  64.                 return index
  65.             else:
  66.                 newLink = list(self.graph.objects(listName,RDF.rest))
  67.                 index += 1
  68.                 if newLink == [RDF.nil]:
  69.                     raise ValueError("%s is not in %s"%(item,self.uri))
  70.                 elif not newLink:
  71.                     raise Exception("Malformed RDF Collection: %s"%self.uri)
  72.                 else:
  73.                     assert len(newLink)==1, "Malformed RDF Collection: %s"%self.uri
  74.                     listName = newLink[0]
  75.  
  76.     def __getitem__(self, key):
  77.         """TODO"""
  78.         c = self._get_container(key)
  79.         if c:
  80.             v = self.graph.value(c, RDF.first)
  81.             if v:
  82.                 return v
  83.             else:
  84.                 raise KeyError, key
  85.         else:
  86.             raise IndexError, key
  87.  
  88.     def __setitem__(self, key, value):
  89.         """TODO"""
  90.         c = self._get_container(key)
  91.         if c:
  92.             self.graph.add((c, RDF.first, value))
  93.         else:
  94.             raise IndexError, key
  95.  
  96.  
  97.     def __delitem__(self, key):
  98.         """..."""
  99.         self[key] # to raise any potential key exceptions
  100.         graph = self.graph
  101.         current = self._get_container(key)
  102.         assert current
  103.         if key==len(self)-1:
  104.             graph.remove((current, RDF.first, None))
  105.             graph.remove((current, RDF.rest, None))
  106.         else:
  107.             next = self._get_container(key+1)
  108.             assert next
  109.             first = graph.value(next, RDF.first)
  110.             rest = graph.value(next, RDF.rest)
  111.  
  112.             graph.set((current, RDF.first, first))
  113.             graph.set((current, RDF.rest, rest))
  114.  
  115.     def __iter__(self):
  116.         """Iterator over items in Collections"""
  117.         return self.graph.items(self.uri)
  118.  
  119.     def append(self, item):
  120.         container = self.uri
  121.         graph = self.graph
  122.         while True:
  123.             first = graph.value(container, RDF.first)
  124.             if first is None:
  125.                 graph.add((container, RDF.first, item))
  126.                 return
  127.             else:
  128.                 rest = graph.value(container, RDF.rest)
  129.                 if rest:
  130.                     container = rest
  131.                 else:
  132.                     node = BNode()
  133.                     graph.add((container, RDF.rest, node))
  134.                     container = node
  135.  
  136.     def clear(self):
  137.         container = self.uri
  138.         graph = self.graph
  139.         while container:
  140.             rest = graph.value(container, RDF.rest)
  141.             graph.remove((container, RDF.first, None))
  142.             graph.remove((container, RDF.rest, None))
  143.             container = rest
  144. def test():
  145.     import doctest
  146.     doctest.testmod()
  147.  
  148. if __name__=="__main__":
  149.     test()
  150.  
  151.     g = Graph()
  152.  
  153.     c = Collection(g, BNode())
  154.  
  155.     assert len(c)==0
  156.  
  157.     c = Collection(g, BNode(), [Literal("1"), Literal("2"), Literal("3"), Literal("4")])
  158.  
  159.     assert len(c)==4
  160.  
  161.     assert c[1]==Literal("2"), c[1]
  162.  
  163.     del c[1]
  164.  
  165.     assert list(c)==[Literal("1"), Literal("3"), Literal("4")], list(c)
  166.  
  167.     try:
  168.         del c[500]
  169.     except IndexError, i:
  170.         pass
  171.  
  172.     c.append(Literal("5"))
  173.  
  174.     print list(c)
  175.  
  176.     for i in c:
  177.         print i
  178.  
  179.     del c[3]
  180.  
  181.     c.clear()
  182.  
  183.     assert len(c)==0
  184.  
  185.